package net.lookyou.boot.demo.config.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p> Security 核心配置类 </p>
 *
 * @author： zhengqing <br/>
 * @date： 2019/9/30$ 10:58$ <br/>
 * @version： <br/>
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    /**
     * 用户密码校验过滤器
     */
    private final CustomerAuthenticationProcessingFilter customerAuthenticationProcessingFilter;

    public SecurityConfig(CustomerAuthenticationProcessingFilter customerAuthenticationProcessingFilter) {
        this.customerAuthenticationProcessingFilter = customerAuthenticationProcessingFilter;
    }

    /**
     * 权限配置
     * @param http
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.antMatcher("/**").authorizeRequests();

        // 禁用CSRF 开启跨域
        http.csrf().disable().cors();

        // 标识只能在 服务器本地ip[127.0.0.1或localhost] 访问`/home`接口，其他ip地址无法访问
        registry.antMatchers("/home").hasIpAddress("127.0.0.1");
        // 允许匿名的url - 可理解为放行接口 - 多个接口使用,分割
        //registry.antMatchers("/login", "/index").permitAll();
        // OPTIONS(选项)：查找适用于一个特定网址资源的通讯选择。 在不需执行具体的涉及数据传输的动作情况下， 允许客户端来确定与资源相关的选项以及 / 或者要求， 或是一个服务器的性能
        registry.antMatchers(HttpMethod.OPTIONS, "/**").denyAll();
        // 自动登录 - cookie储存方式
        registry.and().rememberMe();
        // 其余所有请求都需要认证
        registry.anyRequest().authenticated();
        // 防止iframe 造成跨域
        registry.and().headers().frameOptions().disable();

        // 自定义过滤器认证用户名密码
        http.addFilterAt(customerAuthenticationProcessingFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }


    /**
     * 忽略拦截url或静态资源文件夹
     * @throws Exception
     */
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        //test免登陆
        return (web) -> web.ignoring().antMatchers(HttpMethod.GET,
                "/favicon.ico", "/*.html", "/**/*.css", "/**/*.js", "/login", "/index");
    }
}

